package ru.spb.osll.myfit.server.handler;

import java.io.FileNotFoundException;
import java.util.Vector;

import org.apache.log4j.Logger;

import ru.spb.osll.myfit.common.Include;
import ru.spb.osll.myfit.common.IncludeError;
import ru.spb.osll.myfit.common.Page;
import ru.spb.osll.myfit.common.PageElement;
import ru.spb.osll.myfit.common.SetUp;
import ru.spb.osll.myfit.common.Table;
import ru.spb.osll.myfit.common.TableStyle;
import ru.spb.osll.myfit.common.TearDown;
import ru.spb.osll.myfit.common.TextParsingTools;
import ru.spb.osll.myfit.server.parser.PageUtils;
import ru.spb.osll.myfit.server.parser.RecursiveIncludeException;
import ru.spb.osll.myfit.server.parser.TableElementParser;

/**
 * @author kdv
 * 
 */
public class ContentHandler implements Handler {
  private Logger log = Logger.getLogger(getClass());
  private PageLoader m_pageLoader;
  private TableElementParser m_tableParser = new TableElementParser();
  private final String m_root;
  public ContentHandler(String root,
                        PageLoader pageLoader) {
    m_root = root;
    m_pageLoader = pageLoader;
  }

  @Override
  public Table getTable(Vector<String> rawTable, TableStyle tableStyle) {
    Table table = m_tableParser.parseTable(rawTable);
    table.setStyle(tableStyle);
    return table;
  }
  
  @Override
  public Page loadPage(String pagePath){
    Page page = null;
    try {
      page = m_pageLoader.loadPage(m_root, PageUtils.getFullPath(m_root, pagePath), pagePath);
    } catch (FileNotFoundException e) {
      page = new Page();
    }
    
    addSetUpAndTearDown(page, pagePath, m_root);
    return page;
  }
  

  @Override
  public Page loadPageFromDirectory(String pageName, String fromRoot) {  
    Page page = null;
    try {
      page = m_pageLoader.loadPage(fromRoot, PageUtils.getFullPath(fromRoot, pageName), pageName);
    } catch (FileNotFoundException e) {
      return null;
    }
    
    addSetUpAndTearDown(page, pageName, fromRoot);
    return page;
  }

  @Override
  public PageElement loadInclude(String includePagePath, String parentPagePath) {
    try {
      Page page = m_pageLoader.loadIncludePage(m_root, parentPagePath, includePagePath);
       return new Include(includePagePath, page);
     } catch (FileNotFoundException e) {
       return new IncludeError(includePagePath,
           createPageWithError(e.getMessage()));
     } catch (RecursiveIncludeException e) {
       String message = TextParsingTools.RECURSIVE_CALL + parentPagePath +
           " from the page " + e.getMessage();
       return new IncludeError(includePagePath, createPageWithError(message));
     }
  }
  
  private Page createPageWithError(String errorMessage){
   return m_pageLoader.createPageWithError(errorMessage);
  }
  
  
  private void addSetUpAndTearDown(Page page, String pagePath, String root){
    PageElement setUp = getSetUpOrTearDown(root, pagePath, TextParsingTools.SETUP);
    if (setUp != null) {
      page.insertElement(setUp, 0);
    }

    PageElement tearDown = getSetUpOrTearDown(root, pagePath,
        TextParsingTools.TEARDOWN);
    if (tearDown != null) {
      page.insert(tearDown);
    }

  }
  
  private PageElement getSetUpOrTearDown(String root, String pagePath,
                                         String SETUP_OR_TEARDOWN) {
    if (isSetUpOrTearDown(pagePath)) {
      return null;
    }

    String includePath;
    if (pagePath.contains(".")) {
      int beginIndex = pagePath.lastIndexOf(".");
      String rootPath = pagePath.substring(0, beginIndex + 1);
      includePath = rootPath + SETUP_OR_TEARDOWN;
      if (!includePath.startsWith(".")) {
        includePath = "." + includePath;
      }
    } else {
      includePath = "." + SETUP_OR_TEARDOWN;
    }

    try {
      Page page = m_pageLoader.loadPage(root, "", includePath);
      if (SETUP_OR_TEARDOWN.equals(TextParsingTools.SETUP)) {
        return new SetUp(includePath, page);
      } else {
        return new TearDown(includePath, page);
      }
    } catch (FileNotFoundException e) {
      log.debug(SETUP_OR_TEARDOWN + " for page " + pagePath + " not found");
    } 
    return null;
  }

  private boolean isSetUpOrTearDown(String pagePath) {
    String path;
    if (pagePath.contains(".")) {
      int beginIndex = pagePath.lastIndexOf(".");
      path = pagePath.substring(beginIndex + 1);
    } else {
      path = pagePath;
    }

    if (path.equals(TextParsingTools.SETUP)) {
      return true;
    }
    if (path.equals(TextParsingTools.TEARDOWN)) {
      return true;
    }

    return false;
  }
}
